package structdef

import (
	"codejy/globalfunc"
	"fmt"
)

type LineCodeDefinition struct {
	//代码一行内容
	LineContent string
	//代码类型
	LineCodeType int
	//代码行数(用于日志打印)
	LineNum int
	//代码所在文件(用于日志打印)
	LineCodeFile string
}

// 从写ToString方法
func (l LineCodeDefinition) String() string {
	return fmt.Sprintf(`[代码文件:%s,代码行数:%d,代码:%s,代码类型:%d]`, l.LineCodeFile, l.LineNum, l.LineContent, l.LineCodeType)
}

// 创建代码定义
func NewLineCodeDefinition(lineContent string, lineCodeType int, lineNum int, lineCodeFile string) LineCodeDefinition {
	return LineCodeDefinition{LineContent: lineContent, LineCodeType: lineCodeType, LineNum: lineNum, LineCodeFile: lineCodeFile}
}

// 代码转换为LineCode (不分析,单纯的只是结构转换)
func ToLineCode(codeLines []string, codeFilePath string) []LineCodeDefinition {
	//将代码行转换为LineCode
	var codes []LineCodeDefinition
	for i := range codeLines {

		codes = append(codes, NewLineCodeDefinition(codeLines[i], -1, i+1, codeFilePath))
	}
	return codes

}

// 代码分析转换为LineCode
func AnalyseStrLineCode(threadStore *ThreadStore, codeLines []string, codeFilePath string) []LineCodeDefinition {
	//将代码行转换为LineCode
	var codes []LineCodeDefinition
	for i := range codeLines {

		codes = append(codes, NewLineCodeDefinition(codeLines[i], globalfunc.ExecuteFunc("LineAnalysisAll", threadStore, codeLines[i]).(int), i+1, codeFilePath))
	}
	return codes
}

// 只分析函数定义和类型定义,以及类型def方法
func AnalyseTypeOrFunLineCode(codeLines []LineCodeDefinition, codeFilePath string) []LineCodeDefinition {

	//将代码行转换为LineCode
	var codes []LineCodeDefinition
	for i := range codeLines {
		codes = append(codes, NewLineCodeDefinition(codeLines[i].LineContent, globalfunc.ExecuteFunc("LineAnalysisTypeAndFun", codeLines[i].LineContent).(int), codeLines[i].LineNum, codeFilePath))
	}
	return codes
}

// 二次分析 ,因为执行的代码可能会改变之前代码的类型或者之后代码的类型
// 后期会做代码跳转如果跳转到前面的话,就会出问题,或者跳转到后面的话也会出问题
// 所以需要每次执行一行代码后,上下文中的所有代码都需要重新分析一遍
func AnalyseLineCodeDefinitions(threadStore *ThreadStore, codeLines []LineCodeDefinition, codeFilePath string) []LineCodeDefinition {
	var codes []LineCodeDefinition

	for i := range codeLines {

		codes = append(codes, NewLineCodeDefinition(codeLines[i].LineContent, globalfunc.ExecuteFunc("LineAnalysisAll", threadStore, codeLines[i].LineContent).(int), codeLines[i].LineNum, codeFilePath))
	}
	return codes

}

// 当前执行的单行代码分析
func AnalyseLineCodeDefinition(threadStore *ThreadStore, codeLine LineCodeDefinition, codeFilePath string) LineCodeDefinition {
	return NewLineCodeDefinition(codeLine.LineContent, globalfunc.ExecuteFunc("LineAnalysisAll", threadStore, codeLine.LineContent).(int), codeLine.LineNum, codeFilePath)
}

// 命令行,执行,行代码,分析
func AnalyseLineCodeDefinitionsByCmd(threadStore *ThreadStore, codeLine string, codeFilePath string) LineCodeDefinition {
	return NewLineCodeDefinition(codeLine, globalfunc.ExecuteFunc("CmdLineAnalysis", threadStore, codeLine).(int), 0, codeFilePath)
}
